package controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Properties;

import model.PluginStorage;
import interfaces.IPlateFormeAPI;
import interfaces.IPlateformePlugin;

public class PlateformeCore {

	public static IPlateFormeAPI papi;
	private PluginFactory plugFact;
	private PluginStorage storage;

	public PlateformeCore(){
		this.plugFact = new PluginFactory();
		this.storage = new PluginStorage();
		papi = new PlateformeAPI();
	}

	public void launch() {
		// TODO Auto-generated method stub
		this.refreshListOfAvailablePlugins();
	}

	public void refreshListOfAvailablePlugins() {
		this.storage.cleanListOfAvailablePlugins();
		
		Properties plug_cfg = new Properties();
		try {
			plug_cfg.load(new FileReader(this.storage.getPluginPath().getPluginsConfigPath()));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		File pluginFolder = new File(plug_cfg.getProperty("PLUGIN_PATH"));
		ArrayList<URL> urls = new ArrayList<URL>();
		Properties onePlugCfg = new Properties();
		
		int i=0;
		for(i=0;i<pluginFolder.list().length;i++){
			if(pluginFolder.list()[i].endsWith(".cfg")){
				String pluginCFGFile=pluginFolder.list()[i];
				try {
					onePlugCfg.load(new FileReader(pluginFolder.toString()+"/"+pluginCFGFile));
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				
				try {
					urls.add(new URL("file:"+onePlugCfg.getProperty("BIN_PATH")));
				} catch (MalformedURLException e) {
					e.printStackTrace();
				}
			}
		}
		//on créé le classloader
		URL[] urlsArray = Arrays.copyOf(urls.toArray(), urls.toArray().length, URL[].class);
		URLClassLoader ucl = new URLClassLoader(urlsArray, ClassLoader.getSystemClassLoader());
		
		//on parcours les .cfg des plugins
		for(i=0;i<pluginFolder.list().length;i++){
			if(pluginFolder.list()[i].endsWith(".cfg")){
				String pluginCFGFile=pluginFolder.list()[i];
				try {
					onePlugCfg.load(new FileReader(pluginFolder.toString()+"/"+pluginCFGFile));
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				
				//on précharge les plugins (via lazyplugin)
				String mainClass = onePlugCfg.getProperty("MAIN_CLASS").replace(".java", "");
				String namePlugin = onePlugCfg.getProperty("PLUGIN_NAME");
				if(!this.storage.isThePluginLoaded(namePlugin) && !this.storage.isThePluginAlreadyAvailable(namePlugin)){
					IPlateformePlugin plug = plugFact.getPlugin(mainClass,ucl);
					this.storage.addAvailablePlugin(namePlugin,plug);
				}
			}
		}
	}
	
	public void loadPlugin(String namePlugin){
		//TODO enlever le plugin de la liste available
		IPlateformePlugin ipp = this.storage.getPluginByName(namePlugin);
		ipp.load();
		this.storage.addLoadedPlugin(namePlugin, ipp);
	}

	public void unloadPlugin(String s){
		this.storage.unloadPlugin(s);
		System.gc();
	}

	public PluginStorage getPluginStorage() {
		return this.storage;
	}	
}
